/*
 * z描          述:  <描述>
 * 修  改   人:  PengQingyang
 * 修改时间:  2022年5月14日
 * <修改描述:>
 */
package com.tx.component.attachment.starter;

import javax.sql.DataSource;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.transaction.PlatformTransactionManager;

import com.tx.component.attachment.AttachmentContextConstants;
import com.tx.component.attachment.context.AttachmentContext;
import com.tx.component.attachment.context.AttachmentEngineFactory;
import com.tx.component.attachment.dao.AttachmentInstanceDao;
import com.tx.component.attachment.dao.AttachmentTagDao;
import com.tx.component.attachment.service.AttachmentDetailService;
import com.tx.component.attachment.service.AttachmentInstanceService;
import com.tx.component.attachment.service.AttachmentTagService;
import com.tx.component.file.context.FileEngine;
import com.tx.component.file.starter.FileContextAutoConfiguration;
import com.tx.core.exceptions.util.AssertUtils;

/**
 * 附件容器自动配置器<br/>
 * <功能详细描述>
 * 
 * @author  PengQingyang
 * @version  [版本号, 2022年5月14日]
 * @see  [相关类/方法]
 * @since  [产品/模块版本]
 */
@Configuration
@AutoConfigureAfter({ FileContextAutoConfiguration.class })
@EnableConfigurationProperties(AttachmentContextProperties.class)
@ConditionalOnClass({ AttachmentContext.class })
@ConditionalOnSingleCandidate(DataSource.class)
@ConditionalOnBean({ PlatformTransactionManager.class, FileEngine.class })
@ConditionalOnProperty(prefix = AttachmentContextConstants.PROPERTIES_PREFIX, value = "enable", havingValue = "true")
@Import({ AttachmentContextPersisterConfiguration.class })
public class AttachmentContextAutoConfiguration
        implements InitializingBean, ApplicationContextAware {
    
    /** spring容器句柄　*/
    @SuppressWarnings("unused")
    private ApplicationContext applicationContext;
    
    /** 基础包 */
    @SuppressWarnings("unused")
    private String basePackages;
    
    /** 事务管理器 */
    @SuppressWarnings("unused")
    private PlatformTransactionManager transactionManager;
    
    /** 属性文件 */
    private AttachmentContextProperties properties;
    
    /** application.name */
    @Value(value = "${spring.application.name}")
    private String applicationName;
    
    /** 容器所属模块：当该值为空时，使用spring.application.name的内容 */
    private String module;
    
    /** <默认构造函数> */
    public AttachmentContextAutoConfiguration(
            AttachmentContextProperties properties,
            PlatformTransactionManager transactionManager) {
        super();
        this.properties = properties;
        this.transactionManager = transactionManager;
    }
    
    /**
     * @param applicationContext
     * @throws BeansException
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext)
            throws BeansException {
        this.applicationContext = applicationContext;
    }
    
    /**
     * @throws Exception
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        //初始化包名
        if (!StringUtils.isBlank(this.applicationName)) {
            this.module = this.applicationName;
        }
        if (!StringUtils.isEmpty(this.properties.getModule())) {
            this.module = this.properties.getModule();
        }
        AssertUtils.notEmpty(this.module, "module is empty.");
    }
    
    /**
     * attachmentTagService
     * <功能详细描述>
     * @param attachmentTagDao
     * @return [参数说明]
     * 
     * @return AttachmentTagService [返回类型说明]
     * @exception throws [异常类型] [异常说明]
     * @see [类、类#方法、类#成员]
     */
    @Bean(name = "attach.attachmentTagService")
    public AttachmentTagService attachmentTagService(
            AttachmentTagDao attachmentTagDao) {
        AttachmentTagService service = new AttachmentTagService(
                attachmentTagDao);
        return service;
    }
    
    /**
     * attachmentInstanceService
     * <功能详细描述>
     * @param attachmentInstanceDao
     * @param attachmentTagService
     * @return [参数说明]
     * 
     * @return AttachmentInstanceService [返回类型说明]
     * @exception throws [异常类型] [异常说明]
     * @see [类、类#方法、类#成员]
     */
    @Bean(name = "attach.attachmentInstanceService")
    public AttachmentInstanceService attachmentInstanceService(
            AttachmentInstanceDao attachmentInstanceDao,
            AttachmentTagService attachmentTagService) {
        AttachmentInstanceService service = new AttachmentInstanceService(
                this.module, attachmentInstanceDao, attachmentTagService);
        return service;
    }
    
    /**
     * 附件详情业务层
     * <功能详细描述>
     * @param attachmentInstanceService
     * @return [参数说明]
     * 
     * @return AttachmentDetailService [返回类型说明]
     * @exception throws [异常类型] [异常说明]
     * @see [类、类#方法、类#成员]
     */
    @Bean(name = "attach.attachmentDetailService")
    public AttachmentDetailService attachmentDetailService(
            AttachmentInstanceService attachmentInstanceService) {
        AttachmentDetailService service = new AttachmentDetailService(
                attachmentInstanceService);
        return service;
    }
    
    /**
     * 注册文件容器<br/>
     * <功能详细描述>
     *
     * @return FileContextFactroy [返回类型说明]
     * @throws throws [异常类型] [异常说明]
     * @see [类、类#方法、类#成员]
     */
    @Bean(name = "attachmentContextEngine")
    public AttachmentEngineFactory attachmentContextEngine(
            AttachmentDetailService attachmentDetailService) {
        AttachmentEngineFactory fileContext = new AttachmentEngineFactory();
        fileContext.setAttachmentDetailService(attachmentDetailService);
        return fileContext;
    }
    
}
